 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Geolocation
{
    /// <summary>
    ///     A rectangle shape of coordinates.
    /// </summary>
    public struct BoundingBox
    {
        /// <summary>
        ///     Top left coordinates of the bounding box.
        /// </summary>
        public readonly Coordinates TopLeft;
        /// <summary>
        ///     Bottom right coordinates of the bounding box.
        /// </summary>
        public readonly Coordinates BottomRight;

        /// <summary>
        /// Initializes a new instance of the <see cref="BoundingBox"/> struct.
        /// </summary>
        /// <param name="topLeft">The top left.</param>
        /// <param name="bottomRight">The bottom right.</param>
        public BoundingBox(Coordinates topLeft, Coordinates bottomRight)
        {
            this.TopLeft = topLeft;
            this.BottomRight = bottomRight;
        }

        /// <summary>
        /// Determines whether the specified coordinates are within the bounding box.
        /// </summary>
        /// <param name="coordinates">The coordinates.</param>
        /// <returns>
        ///   <c>true</c> if [contains] [the specified coordinates]; otherwise, <c>false</c>.
        /// </returns>
        public bool Contains(Coordinates coordinates)
        {
            return (coordinates.Longitude >= this.TopLeft.Longitude &&
                coordinates.Longitude <= this.BottomRight.Longitude) &&
                (coordinates.Latitude >= this.TopLeft.Latitude &&
                coordinates.Latitude <= this.BottomRight.Latitude);
        }
        
        /// <summary>
        /// Determines the center coordinates of the bounding box
        /// </summary>
        /// <returns></returns>
        public Coordinates GetCenter()
        {
        
           double X1 = 0;
           double Y2 = 0;
           double Z3 = 0;
        
           Coordinates[] t = {
              this.BottomRight,
              this.TopLeft
           };
        
           foreach (Coordinates i in t) {
              double lat4 = i.Latitude * Math.PI / 180;
              double lon5 = i.Longitude * Math.PI / 180;
        
              double x6 = Math.Cos(lat4) * Math.Cos(lon5);
              double y7 = Math.Cos(lat4) * Math.Sin(lon5);
              double z8 = Math.Sin(lat4);
        
              X1 += x6;
              Y2 += y7;
              Z3 += z8;
           }
        
           X1 = X1 / 2;
           Y2 = Y2 / 2;
           Z3 = Z3 / 2;
        
           double Lon9 = Math.Atan2(Y2, X1);
           double Hyp = Math.Sqrt(X1 * X1 + Y2 * Y2);
           double Lat10 = Math.Atan2(Z3, Hyp);
        
           return new Coordinates(Lon9 * 180 / Math.PI, Lat10 * 180 / Math.PI);
        }

    }
}
